#include	"lp_global_vars.h"

config_info * get_config_info() {
	return config_info_sample;
}
//-------------------------------------------------------------
void lp_config_parser(const char * config_path, int proposer_id, int learner_id, int is_proposer) {
	char flag;
	char *match;
	config_info_sample = malloc(sizeof(config_info));
	assert(config_info_sample != NULL);

	config_info_sample->proposer_id = proposer_id;
	config_info_sample->learner_id = learner_id;

	match = "acceptor";
	flag = 'a';
	get_ip_port(config_path, get_config_info(), match, flag);

	match = "learner";
	flag = 'l';
	get_ip_port(config_path, get_config_info(), match, flag);

	match = "learner_to_acceptor";
	flag = 't';
	get_ip_port(config_path, get_config_info(), match, flag);

	match = "multicast";
	get_multicast_address(config_path, config_info_sample, match);

	match = "proposer_to_multicaster";
	get_multicast_address_for_proposer(config_path, config_info_sample, match);

	lp_create_sockets(config_info_sample, is_proposer);
}
//-------------------------------------------------------------
void get_ip_port(const char* config_file, config_info * config, const char * match, char flag) {

	FILE * fp;
	char line[STRING_SIZE];
	char word[STRING_SIZE];
	int last_index = -1, server_counter = 0, learner_id;

	fp = fopen(config_file, "r");
	while (!feof(fp)) {
		if (fgets(line, STRING_SIZE, fp) != 0) {
			last_index = get_substr(0, strlen(line) - 1, line, word);

			if (strcmp(word, match) == 0) {

				last_index = get_substr(last_index + 1, strlen(line) - 1, line, word);
				if (flag == 'a')
					config->server_infos[server_counter].server_id = atoi(word);
				else if (flag == 't')
					learner_id = atoi(word);
				else if (flag == 'l')
					config->learner_infos[server_counter].learner_id = atoi(word);

				last_index = get_substr(last_index + 1, strlen(line) - 1, line, word);
				if (flag == 'a')
					memcpy(config->server_infos[server_counter].ip, word, strlen(word));
				else if (flag == 't')
					config->learner_infos[learner_id].acceptor_id = atoi(word);
				if (flag == 'l')
					memcpy(config->learner_infos[server_counter].ip, word, strlen(word));

				if (flag != 't') {
					last_index = get_substr(last_index + 1, strlen(line) - 1, line, word);
					if (flag == 'a')
						config->server_infos[server_counter].port = atoi(word);
					if (flag == 'l')
						config->learner_infos[server_counter].acceptor_port = atoi(word);
				}
				server_counter++;
			}
		}
	}
	if (flag == 'a')
		config->total_num_acceptors = server_counter;
	else if (flag == 'l')
		config->total_num_learners = server_counter;

	fclose(fp);
}
//-------------------------------------------------------------
void get_multicast_address(const char* config_file, config_info * config, const char * match) {

	FILE * fp;
	char line[STRING_SIZE], word[STRING_SIZE];
	int last_index = -1;

	fp = fopen(config_file, "r");
	while (!feof(fp)) {
		if (fgets(line, STRING_SIZE, fp) != 0) {
			last_index = get_substr(0, strlen(line) - 1, line, word);
			if (strcmp(word, match) == 0) {
				last_index = get_substr(last_index + 1, strlen(line) - 1, line, word);
				strcpy(config->multicast_ip, word);

				last_index = get_substr(last_index + 1, strlen(line) - 1, line, word);
				config->multicast_port = atoi(word);
			}
		}
	}
	fclose(fp);
}
//-------------------------------------------------------------
void get_multicast_address_for_proposer(const char* config_file, config_info * config, const char * match) {

	FILE * fp;
	char line[STRING_SIZE], word[STRING_SIZE];
	int last_index = -1;

	fp = fopen(config_file, "r");
	while (!feof(fp)) {
		if (fgets(line, STRING_SIZE, fp) != 0) {
			last_index = get_substr(0, strlen(line) - 1, line, word);
			if (strcmp(word, match) == 0) {
				last_index = get_substr(last_index + 1, strlen(line) - 1, line, word);
				config->proposer_to_multicaster_port = atoi(word);
			}
		}
	}
	fclose(fp);
}
//-------------------------------------------------------------
void lp_create_sockets(config_info *config, int is_proposer) {

	//socket for the learner to connect to the corresponding acceptor to ask for retransmissions: TCP
	int port = config->learner_infos[config->learner_id].acceptor_port;
	char *ip = config->server_infos[config->learner_infos[config->learner_id].acceptor_id].ip;

	printf("Learner, creating TCP client socket to the acceptor for lost packets.....%s %d\n", ip, port);
	config->learner_infos[config->learner_id].learner_to_acceptor_sid = create_tcp_client_socket(port, ip);
	printf("TCP socket successfully created at: %d\n", config->learner_infos[config->learner_id].learner_to_acceptor_sid);

	//socket for the proposer to connect to the multicaster. udp client socket:
	if (is_proposer == 1) {
		printf("Proposer creating a udp socket to send values to the multicaster....\n");
		config->proposer_to_multicaster_sid = create_udp_client_socket(config->server_infos[0].ip, config->proposer_to_multicaster_port);
		printf("Proposer successfully created the socket at: %d\n", config->proposer_to_multicaster_sid);
	}
	// socket for the learner to listen to all the multicast messages. 
	printf("Learner: creating ip-multicast receiving socket....%s\n", config->multicast_ip);
	config->server_infos[config->learner_id].multicast_recv_sid = create_ip_multicast_receiver_socket(config->multicast_ip, config->learner_infos[config->learner_id].ip, config->multicast_port);
	printf("IP multicast socket created with sid: %d\n", config->server_infos[config->learner_id].multicast_recv_sid);

}
//--------getters----------------------------------------------
int GET_SID_FOR_PROPOSER_TO_MULTICASTER() {
	return config_info_sample->proposer_to_multicaster_sid;
}

struct sockaddr_in* GET_SOCKADDR() {
	return getAddr(config_info_sample->multicast_port, config_info_sample->multicast_ip);
}
